package com.avalon.core.field;

import com.avalon.core.context.Context;
import com.avalon.core.face.field.IFieldDefaultValue;
import com.avalon.core.service.AbstractService;
import com.avalon.core.util.ObjectUtils;

import java.lang.reflect.Type;

/**
 * 两表关联，多对多关系，未实现与测试，暂时不可用
 */
public class Many2manyField extends RelationField {

    private AbstractService abstractService;
    private AbstractService masterService;

    private AbstractService getMasterService() {
        return masterService;
    }

    protected void setMasterService(AbstractService masterService) {
        this.masterService = masterService;
    }

    private String relativeServiceName;

    public String getRelativeServiceName() {
        return relativeServiceName;
    }

    @Override
    public String getRelativeFieldName() {
        return null;
    }

    @Override
    public AbstractService getRelativeService() {
        return getService().getServiceBean(getRelativeServiceName());
    }

    protected void setRelativeServiceName(String relativeServiceName) {
        this.relativeServiceName = relativeServiceName;
    }

    private AbstractService getRelativeAbstractService() {
        if (ObjectUtils.isNotNull(abstractService)) return abstractService;
        synchronized (this) {
            if (ObjectUtils.isNotNull(abstractService)) return abstractService;
            abstractService = Context.getServiceBeanInstance(getRelativeServiceName());
            return abstractService;
        }
    }

    public String getTableName() {
        return getMasterService().getServiceTableName() +
                "_" + getRelativeAbstractService().getServiceTableName() + "_ref";
    }

    public StringBuilder createTable() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("CREATE TABLE IF NOT EXISTS ");
        stringBuilder.append(getTableName());
        stringBuilder.append(" ( ");
        Field primaryKeyField = getMasterService().getPrimaryKeyField();
        stringBuilder.append(primaryKeyField.getFieldName());
        stringBuilder.append(" ");
        stringBuilder.append(primaryKeyField.getCreateTableSql());
        stringBuilder.append(",");
        stringBuilder.append(getMasterService().getServiceTableName()).
                append("_").append(primaryKeyField.getFieldName()).append(" ");
        stringBuilder.append(primaryKeyField.getSampleCreateTableSql());
        stringBuilder.append(",");
        primaryKeyField = getRelativeAbstractService().getPrimaryKeyField();
        stringBuilder.append(getRelativeAbstractService().getServiceTableName()).
                append("_").append(primaryKeyField.getFieldName()).append(" ");
        stringBuilder.append(primaryKeyField.getSampleCreateTableSql());
        stringBuilder.append(" ) ");
        return stringBuilder;
    }

    public StringBuilder dropTable() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("DROP TABLE ");
        stringBuilder.append(getTableName());
        return stringBuilder;
    }

    public Many2manyField(String relativeServiceName) {
        this("", relativeServiceName);
    }

    @Override
    public Type getFieldType() {
        return Many2manyField.class;
    }

    @Override
    public Object getSqlValue(Object value) {
        return null;
    }

    @Override
    public String getCreateTableSql() {
        return null;
    }

    @Override
    public String getSampleCreateTableSql() {
        return null;
    }

    public Many2manyField(String label, String relativeServiceName) {
        this(label, false, relativeServiceName);
    }

    public Many2manyField(String label, Boolean isRequired, String relativeServiceName) {
        this(label, isRequired, false, relativeServiceName);
    }

    public Many2manyField(String label, Boolean isRequired, Boolean isReadonly, String relativeServiceName) {
        this(label, isRequired, isReadonly, IFieldDefaultValue.getFieldDefaultValue(), relativeServiceName);
    }

    public Many2manyField(String label, Boolean isRequired, Boolean isReadonly,
                          IFieldDefaultValue defaultValue, String relativeServiceName) {
        this(label, isRequired, isReadonly, defaultValue, relativeServiceName, false, false);
    }

    public Many2manyField(String label, Boolean isRequired, Boolean isReadonly,
                          IFieldDefaultValue defaultValue,
                          String relativeServiceName, Boolean isPrimaryKey,
                          Boolean isAutoIncrement) {
        super(label, isRequired, isReadonly, true,
                defaultValue, isPrimaryKey, isAutoIncrement);
        this.setRelativeServiceName(relativeServiceName);
    }

    @Override
    public Integer getSqlType() {
        return null;
    }
}
